﻿using System;
using System.Collections.Generic;
using Library.OrmEnterpriseEntity.TableInfo;
using Library.Util;

namespace Library.OrmEnterpriseEntity {
	public class QueryExpBuilder : ExpressionBuilder {
		public override ExpressionType ExpType {
			get { return ExpressionType.Exp; }
		}
		private readonly IList<ExpressionBuilder> _builds;

		internal QueryExpBuilder(QueryStatement statement)
			: this() {
			Statement = statement;
		}
		public sealed override QueryStatement Statement {
			get {
				return base.Statement;
			}
			set {
				base.Statement = value;
				foreach (var expressionBuilder in _builds) {
					expressionBuilder.Statement = value;
				}
				OnStatementChanged();
			}
		}
		protected virtual void OnStatementChanged() {
		}


		protected QueryExpBuilder() {
			_builds = new BuilderCollection(this);

		}


		//public QueryExpBuilder(DbColumnView first, QueryOperator queryOperator, QueryParameter parameter)
		//  : this() {
		//  _builds.Add(new QueryParmBuilder(first, queryOperator, parameter));
		//}

		public QueryExpBuilder(DbColumnView first, QueryOperator queryOperator, object value)
			: this() {
			_builds.Add(new QueryParmBuilder(first, queryOperator, value));
		}
		public QueryExpBuilder(DbColumnView first, string massFilter, EventHandler<CustomValueParseEventArgs> parserTextCallback)
			: this() {
			_builds.Add(new QueryMassBuilder(first, massFilter, parserTextCallback));
		}
		public QueryExpBuilder(DbColumnView first, string massFilter)
			: this(first, massFilter, null) {
		}



		public QueryExpBuilder(DbColumnView first, QueryOperator queryOperator, DbColumnView second)
			: this() {
			_builds.Add(new QueryColumnBuilder(first, queryOperator, second));
		}

		//public QueryExpBuilder And(DbColumnView first, QueryOperator queryOperator, QueryParameter parameter) {

		//  _builds.Add(new QueryWrapBuilder(new QueryParmBuilder(first, queryOperator, parameter), ExpressionOperator.And));
		//  return this;
		//}

		public QueryExpBuilder And(DbColumnView first, QueryOperator queryOperator, object value) {
			_builds.Add(new QueryWrapBuilder(new QueryParmBuilder(first, queryOperator, value), ExpressionOperator.And));
			return this;
		}

		public QueryExpBuilder And(DbColumnView first, QueryOperator queryOperator, DbColumnView second) {
			_builds.Add(new QueryWrapBuilder(new QueryColumnBuilder(first, queryOperator, second), ExpressionOperator.And));
			return this;
		}
		public QueryExpBuilder And(DbColumnView first, string massFilter, EventHandler<CustomValueParseEventArgs> parserTextCallback) {
			_builds.Add(new QueryWrapBuilder(new QueryMassBuilder(first, massFilter, parserTextCallback), ExpressionOperator.And));
			return this;
		}
		public QueryExpBuilder And(DbColumnView first, string massFilter) {
			return And(first, massFilter, null);
		}
		//public QueryExpBuilder Or(DbColumnView first, QueryOperator queryOperator, QueryParameter parameter) {
		//  _builds.Add(new QueryWrapBuilder(new QueryParmBuilder(first, queryOperator, parameter), ExpressionOperator.Or));
		//  return this;
		//}

		public QueryExpBuilder Or(DbColumnView first, QueryOperator queryOperator, object value) {
			_builds.Add(new QueryWrapBuilder(new QueryParmBuilder(first, queryOperator, value), ExpressionOperator.Or));
			return this;
		}
		public QueryExpBuilder Or(DbColumnView first, string massFilter, EventHandler<CustomValueParseEventArgs> parserTextCallback) {
			_builds.Add(new QueryWrapBuilder(new QueryMassBuilder(first, massFilter, parserTextCallback), ExpressionOperator.Or));
			return this;
		}
		public QueryExpBuilder Or(DbColumnView first, string massFilter) {
			return Or(first, massFilter, null);
		}

		public QueryExpBuilder Or(DbColumnView first, QueryOperator queryOperator, DbColumnView second) {
			_builds.Add(new QueryWrapBuilder(new QueryColumnBuilder(first, queryOperator, second), ExpressionOperator.Or));
			return this;
		}

		public QueryExpWrapBuilder Add(QueryExpBuilder queryExpression, ExpressionOperator expressionOperator) {

			return new QueryExpWrapBuilder(this, expressionOperator, queryExpression);
		}

		public bool HasExpression { get { return _builds.Count > 0; } }


		public IEnumerable<ExpressionBuilder> Builders { get { return _builds; } }

		private class BuilderCollection : ListBase<ExpressionBuilder> {
			private readonly QueryExpBuilder _queryExpression;
			public BuilderCollection(QueryExpBuilder queryExpression) {
				_queryExpression = queryExpression;
			}
			public override void Insert(int index, ExpressionBuilder item) {
				item.Statement = _queryExpression.Statement;
				base.Insert(index, item);
			}

		}
	}
}
